package org.dromara.common.encrypt.utils;

import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Sm4Util {

    // 示例密钥，实际应用中应使用安全的方式生成和存储密钥
    private static final String KEY = "uhhnqvmx29od27p7";
    // 示例向量，实际应用中应使用安全的方式生成和存储初始化向量
    //需要确保KEY和IV保持16字节长度
    private static final String IV = "920lynyozr51rkoe";

    /**
     * 使用 SM4 算法对明文进行加密。
     *
     * @param plainText 要加密的明文字符串
     * @return 加密后的 Base64 编码字符串
     * @throws Exception 如果加密过程中发生错误
     */
    public static String encrypt(String plainText, String keyIv) throws Exception {
        // 创建一个带填充的缓冲块密码器，使用 CBC 模式和 SM4 引擎
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new SM4Engine()));
        String[] strKeyIv = keyIv.split(" ");
        // 初始化密码器为加密模式，并设置密钥和初始化向量
        // cipher.init(true, new ParametersWithIV(new KeyParameter(KEY.getBytes()), IV.getBytes()));
        cipher.init(true, new ParametersWithIV(new KeyParameter(strKeyIv[0].getBytes()), strKeyIv[1].getBytes()));

        // 将明文转换为字节数组
        byte[] input = plainText.getBytes();
        // 计算输出缓冲区的大小
        byte[] output = new byte[cipher.getOutputSize(input.length)];

        // 进行分步加密
        int length1 = cipher.processBytes(input, 0, input.length, output, 0);
        int length2 = cipher.doFinal(output, length1);

        // 返回加密后的内容，Base64 编码以便于传输和存储
        String result = Base64.getEncoder().encodeToString(output);
        System.out.println(result);
        return result;
    }

    /**
     * 使用 SM4 算法对密文进行解密。
     *
     * @param encryptedText 加密后的 Base64 编码字符串
     * @return 解密后的明文字符串
     * @throws Exception 如果解密过程中发生错误
     */
    public static String decrypt(String encryptedText, String keyIv) throws Exception {
        // 创建一个带填充的缓冲块密码器，使用 CBC 模式和 SM4 引擎
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new SM4Engine()));
        String[] strKeyIv = keyIv.split(" ");
        // 初始化密码器为解密模式，并设置密钥和初始化向量
        // cipher.init(false, new ParametersWithIV(new KeyParameter(KEY.getBytes()), IV.getBytes()));
        cipher.init(false, new ParametersWithIV(new KeyParameter(strKeyIv[0].getBytes()), strKeyIv[1].getBytes()));
        encryptedText = encryptedText.replace("\"", "");
        // 将 Base64 编码的密文解码为字节数组
        byte[] input = Base64.getDecoder().decode(encryptedText.getBytes(StandardCharsets.UTF_8));
        // 计算输出缓冲区的大小
        byte[] output = new byte[cipher.getOutputSize(input.length)];

        // 进行分步解密
        int length1 = cipher.processBytes(input, 0, input.length, output, 0);
        int length2 = cipher.doFinal(output, length1);

        // 返回解密后的明文字符串
        return new String(output, 0, length1 + length2);
    }

    public static void main(String[] args) throws Exception {
        String str = Sm4Util.encrypt("你好呀", "0123456789abcdef 0123456789abcdef");
        System.out.println(str);
        //   String str="IVJBNBMyzwRFgE6xD72Cxz4dLCRnK9AnWS423K3yQDS7WiZ1JeVosP1wRyMPwu4kg09EDevxqZsDg702fSptx8/g3ZtTeUGwUZTo+JfkdVayqySJSB6jBlMqh9EzyqKSZ8kHjURhEL6URK0/X3o+05 LXTcWxrvbEwcLImA7AVNmPq7fqTZ08rjSha5LAi7gUeLT9yFIyxq+fdhig8hMPsszLrVQAxx8Pr9WZof5QIxWlroQz0cnfzRay3Iw+KfzSvVQxPKzWs1lkkUgrooXI7rJ+76 MTjnMWKS5A7rFeXr6pXvxuJsOwqBQbtr4IEEM9dXnKcWb4HKdrtwlBXG3eLg5zd6ApGvGsz6egO/uylzGJ5N9MqsquVnh45uHcULyGBNE0FbKfAjPOh1oeARRP9M90uvB5xr5E593B3/UU/gsVxodVW2YdSdG2ot6Vsfc3sKOUVjlkjA8Pt6vzk5fLKtS/8 U0KW2/pICipfAz2gs55d+xAlhvgA8WOIgKRlLfqLdbAdJ7H+KRJv+Iz3SEFmSWujGkAwqgNPyxJYupD4/OeiKIHkFSmMh5bi1e17dEmb8cG+3 j7zzEgUDBwswkdkaavy/yv4hPl7NhqY4JvWpGQhwIX6AceZyiKEJ+SW2cL4Xp8um8KUH2n8RZD8pv32F2JcH8hPV9UNLCQ95CcAoNN9FAikqZ7wrkNnF+vWADdfmaSi4ITQ2CWwUIFW6XXHwwl/s+bpUuSIDofFGofd+TS9T+MyYiYofAtnpRZBWBsM9m3ZVz3ERugHexRF/VMEJlRNWxAKzj/VFg1Z4DsC1ndMzL9QoJyxJE1mA28jGViP0MJh1h6WhpJobYSof73yj5O0URpUB7GsjjgrdqMEBxw67IpqqB9EeoI5oC5CaN/opW8cpKUsLjVz7wpxH4xrvFTq/kxhaH1AMUPL4yt3NRDECjLO+rgsCUEnx7oPez4zKd4/GWK6AdgtIJzh0RXRAK70wdNY04urRIK4Cg0gARR79kfjM1Wqw/jHLYgCvFLJLqRYy3MyjnCxwxP/48 yYaUDmOdQhssW0vJanIGfznix43ceeMbtdjC+daZVU13yjqTnYkGxfC+K7PU4x0gmErtjp2uE/oTiegwUHc0iRO5/i4kcuZwfI56VIJoOSwMWCvNofI6bkTZLs74YqWdtJWM7bMKNtVnIBGURxkmhlGNSVigHDUTHhSWnQlr0GXR20m/Yx6yob9/sySF5+rKRwngMQKEbBhwkqOC4LJZpxq6wn2FgNfAeudhxn44/BDRyyDWsjGIQ30CBQ5o6vdG3gqxny2JRsCt8lVSqqdjefp85WtWP9hWOb1z5u0VeZVDDX5UsAeYRJhjeq5gbVNQh9hiSLCmYzLQmg+VJ6VH7DbdNMtBktgkiehFPP7oAUvtjPBgRo93OLFT17R8sKHWPikqX5jaW+KMh4ECa6KV45WMIo46ZURr5xHGBu1DnLrMDb0of5FYtToxCmDuSFj9wSG2AZwcHokEeV/FWXqTV+GlDzX3RNnMBWGoC0e2kbo0r0Y0AlWu1Ff4Y4Pr3SAzIzFJpVpYZJA6svvDOJqY8sbY=";
        //   String str1 = "IVJBNBMyzwRFgE6xD72Cxz4dLCRnK9AnWS423K3yQDS7WiZ1JeVosP1wRyMPwu4kfIgu84GQH7quKJnUT0qgrMeq/6puBJnysGSPJK1sEqyF5xZWvd1QuIThDx1RC76PMLW+iuW8GGxxsPHTQRNF+ilYT61hMkLUsf5gxIf6TyCrFUmMGhvQcruB5/1AyjTZ58AsLOc1wpMBnTAdkBtPX4B2YtyCGlkYqmQZIN93j7GipkjnBWBLywwrZ/vHVg8AdV94KqR+QUobroSaTAUiV8qAwfDjH4TFBTL+ZZTQTc/W3ZRNTTAtgnkg7ZI+ybGBpIpMB2FK4qfKMjIJDgWlIoXL/nEJEmI0XAxVz7eVNQrMNdyfAzuACxLUm7sCapw7WfjNvhKDnnZSYS9F8HFZ1v0PZu+DS9Bb6YS93iq8r8aWblMFti1OT7TgcHpzOXylUeiqU8htpWdeSRzxuyx07T9gozE6Pyqy0pj4czAG5TgCxTK2xwKg5rAcxG0XJnbz4YBFAfF0Xz8Cuo2Fcm7sSPhaoOu/zeLlWPHv83aL3G+ahW7IQaAN93V0zGN9yGOfYirYkQStUH8dPXUFWV8yIQJl5kQ3MskHSLPzLqFFUKBFaU1L3vdWo+OS9+CVf72wkvFZvxT+JZvmCBu7aBv08eBH1fTpXUtaJWF7uPPH0IPZ85Sb6tIZJhibWygYB/S10EXD9UvTTVyfJGdNa4Jh6lBx3U29jIUGCU79bQiHDoQML1GKUks+iC2F6qrDiAmfSkDtWokLDPtWB4kQyBaIm4VCJiPti8oGL3gJXl60uNbsKqLwEWdhabTRm8QUC+zrDZw78QHhZ6EFJKPp0A9Cs13slftYarKhb60ErauGWmQDjUMhRwsZIWZ5jrRFBVR/gQE8C8wOQSVfxvBnJpWO9tXyqPURs5tnAGmcfb9BceBUUPds4pQvaJAvANLA9TWXu2eZK7vXvP/0zINFA1ORxfqjG4/lCafHq4Pajv2z2YXq61e0qkWyKzvGPy01dcbAV9Guh+VjB7LXp827l2DvGYAQqJCtLIn6V0DNEQBJtyytRM7i64CRE2IJ531VJbsnWIBaJsr4r3U4V3LuOWoOI3D9Au+n4KTgJYiXwZIZ4MTeUqeq3cXXqevP7/40Ifzw8yZ05S7oMjsfY66/NZwRSKYyvPc5uAG2u9IQ/Fh4aMYt8DNgyiv9oGmSfTQOl/Xcp4zCAbMG3qWML208bQjxAo4xCSAZxnkS8gav+4wpzRmVDuvnFnclIqRWuihYTpb/0DwAmxGq6MPLpNYyTwdKNXqcnKkbS0t37UTa9UQ2g6RhsBOaW76U1KTiTOLPxCbaIr5ob2MfE7DmbaVvmCEBpQEHCSqc2KQ8fWghpZ9/tMDe8w75glrurcq0EMjm/TuidKSU9ZV6sOpK9kMMsn/l7c+jRDgAal6lDa4CP3i7u78pvhurpSGz8lghLkwdPS/FaIYy6yrdTmCpk/3kcyLsYyEtWooEXS1X240wGm6Z8mlsY/mCND3ySIJFLa1F6Tkp6fTl0cWdIXFhTmeM3+vxplg5Gcjja/u93OCa+dc7X44=";
        System.out.println(Sm4Util.decrypt(str, "0123456789abcdef 0123456789abcdef"));
//TiHR5SLOjZF1p6NMzIhRXg==
        // uhhnqvmx29od27p7 920lynyozr51rkoe
        System.out.println(Sm4Util.decrypt("Rtawgj6UF+KMiq4TNF+G7+1hau1MNUeDXexhJsYxJqnkcTSqqTe4ZP7QXGoRDW2/NRElLtB7nYOYVewCfb8a+KimYhkonLdcTss7BPNUztfNBCj+rPnV/JFcnFYebFZ6nYYrltABvcvA0+XuLE+HBPHnXmVL4nPpE1bleeyy3noL0smpmp2PPz52ExnTScH2RBT/yahFL+DUsd+3EmlH/Zl7Ibc3DUEXO9NnaE/nvfG2vy3vZYVC45WFj7CmLQS8Bv1xg6/8zx3VQD5xylgBqg==", "uhhnqvmx29od27p7 920lynyozr51rkoe"));
    }

}
